package com.lk.common.utils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * HttpClient工具类
 * @author lijun
 * @version 2018-05-03
 */
public class HttpClientUtils {
	private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);	//日志记录
	private static RequestConfig requestConfig = null;	//设置请求和传输超时时间

    static{	
        requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
    }
    
    /**
     * post请求传输json参数
     * @param url
     * @param json
     * @return
     */
    public static JSONObject httpPost(String url, JSONObject jsonParam){
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        try{
            if (null != jsonParam){
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                String str = "";
                try{
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    jsonResult = new JSONObject(str);
                }catch (Exception e){
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        }catch (IOException e){
            logger.error("post请求提交失败:" + url, e);
        }finally{
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    /**
     * post请求传输String参数 例如：name=Jack&sex=1&type=2
     * Content-type:application/x-www-form-urlencoded
     * @param url
     * @param strParam
     * @return
     */
    public static JSONObject httpPost(String url, String strParam){
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        try{
            if (null != strParam){
                StringEntity entity = new StringEntity(strParam, "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/x-www-form-urlencoded");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                String str = "";
                try{
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    jsonResult = new JSONObject(str); 
                }catch (Exception e){
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        }catch (IOException e){
            logger.error("post请求提交失败:" + url, e);
        }finally{
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    /**
     * 发送get请求
     * @param url 路径
     * @return
     */
    public static JSONObject httpGet(String url){
        JSONObject jsonResult = null;
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet request = new HttpGet(url);
        request.setConfig(requestConfig);
        try{
            CloseableHttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                HttpEntity entity = response.getEntity();
                String strResult = EntityUtils.toString(entity, "utf-8");
                jsonResult = new JSONObject(strResult);
            }
            else{
                logger.error("get请求提交失败:" + url);
            }
        }catch (IOException e){
            logger.error("get请求提交失败:" + url, e);
        }finally{
            request.releaseConnection();
        }
        return jsonResult;
    }
    
    /**
     * 发送get请求
     * @param url路径
     * @param 请求参数
     * @return
     */
    public static JSONObject httpGet(String url, Map<String, String> params){
        JSONObject jsonResult = null;
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet request = new HttpGet();
        //设定配置
        request.setConfig(requestConfig);
        try{
        	//处理参数
            List<NameValuePair> formParams = setHttpParams(params);
            String param = URLEncodedUtils.format(formParams, "UTF-8");
            request.setURI(URI.create(url + "?" + param));
        	
            //执行请求
            CloseableHttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                HttpEntity entity = response.getEntity();
                String strResult = EntityUtils.toString(entity, "utf-8");
                jsonResult = new JSONObject(strResult);
            }else{
                logger.error("get请求提交失败:" + url);
            }
        }catch (IOException e){
            logger.error("get请求提交失败:" + url, e);
        }finally{
            request.releaseConnection();
        }
        return jsonResult;
    }
    
    /**
     * 发送get请求
     * @param url路径
     * @param 请求参数
     * @return
     */
    public static JSONObject httpAuthGet(String url, Map<String, String> params,String ip,int port,String username,String password){
        JSONObject jsonResult = null;
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet request = new HttpGet();
        //设定配置
        request.setConfig(requestConfig);
        try{
        	//处理参数
            List<NameValuePair> formParams = setHttpParams(params);
            String param = URLEncodedUtils.format(formParams, "UTF-8");
            request.setURI(URI.create(url + "?" + param));
            
            //设置账号密码
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(new AuthScope(ip, port),new UsernamePasswordCredentials(username,password));
            HttpClientContext httpContext = HttpClientContext.create();
            httpContext.setCredentialsProvider(credentialsProvider);
        	
            //执行请求
            CloseableHttpResponse response = client.execute(request,httpContext);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                HttpEntity entity = response.getEntity();
                String strResult = EntityUtils.toString(entity, "utf-8");
                jsonResult = new JSONObject(strResult);
            }else{
                logger.error("get请求提交失败:" + url);
            }
        }catch (IOException e){
            logger.error("get请求提交失败:" + url, e);
        }finally{
            request.releaseConnection();
        }
        return jsonResult;
    }
    
    /**
     * post请求
     * @param url 请求地址
     * @param strParam 请求参数
     * @return
     */
    public static JSONObject httpPost(String url, Map<String,String> params){
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        //设定配置
        httpPost.setConfig(requestConfig);
        try{
        	//处理参数
        	List<NameValuePair> formParams = setHttpParams(params);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formParams, "UTF-8");
            httpPost.setEntity(param);
            
            //执行请求
            CloseableHttpResponse result = httpClient.execute(httpPost);
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                String str = "";
                try{
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    jsonResult = new JSONObject(str); 
                }catch (Exception e){
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        }catch (IOException e){
            logger.error("post请求提交失败:" + url, e);
        }finally{
            httpPost.releaseConnection();
        }
        return jsonResult;
    }
    
    /**
     * 设置请求参数
     * @param
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
        	formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formParams;
    }
}
